# —*— coding: utf-8 -*-
"""

装饰器：
1.函数装饰器
2.类装饰器

"""
import time
import random
import py_global

from functools import wraps, update_wrapper, singledispatch, lru_cache
import logging

logger = logging.getLogger(__name__)


def class_wrapper(cls):
    """
    类装饰器实现
    Parameters
    ----------
    cls

    Returns
    -------

    """
    original_method = cls.instance_method

    def enhance_method(self, *args, **kwargs):
        logger.info('outer class_wrapper')
        original_method(self, *args, **kwargs)
        pass

    cls.instance_method = enhance_method
    return cls


@class_wrapper
class WrapperClass(object):

    def instance_method(self, *args, **kwargs):
        logger.info(f'class:{self.__class__.__name__}')


def function_wrapper(func):
    """
    函数装饰器实现
    Parameters
    ----------
    func

    Returns
    -------

    """

    @wraps(func)
    def wrapper(*args, **kwargs):
        logger.info('exec func start')
        func(*args, **kwargs)
        logger.info('exec func end')

    return wrapper


def arg_wrap(arg=None):
    """
    带有参数的装饰器实现
    Parameters
    ----------
    arg

    Returns
    -------

    """

    def decorator(func):
        @wraps(func)
        def wrapper(*args, **kwargs):
            init_time = time.time()
            func(*args, **kwargs)
            logger.info('%s %s : %s' % (arg, func.__name__, time.time() - init_time))

        return wrapper

    return decorator


@arg_wrap('parameter')
def test(text='info', path='log.log'):
    init_time = time.time()
    n = 10 * random.random()
    line = '%s:%s' % (text, str(n))
    logger.info(line)
    time.sleep(n)
    logger.info('%s : %s' % ('apply_func', time.time() - init_time))
    pass


class Class(object):

    @classmethod
    @function_wrapper
    def function(cls):
        time.sleep(1.2)
        logger.error(f'function')


if __name__ == '__main__':
    # test(text='text', path='path')

    # WrapperClass().instance_method()

    Class().function()

    pass
